package org.yxj.videolibrary.view;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import org.yxj.videolibrary.R;
import org.yxj.videolibrary.i.ControlPlayListener;
import org.yxj.videolibrary.i.PlayVideoListener;
import org.yxj.videolibrary.i.YXJVideoConstant;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 自定义播放器
 * <p>
 * 支持全屏或退出屏幕無縫播放
 *
 * @author on 2022/9/9
 */
public class YXJVideoView extends FrameLayout implements TextureView.SurfaceTextureListener {

    /**
     * 当前状态
     */
    public int state;
    /**
     * 视频总长度
     */
    private int totalLength;
    /**
     * 上一次比较的进度
     */
    private int oldProgress = 0;
    /**
     * 当前进度
     */
    private int currentProgress = 0;
    /**
     * 是否自动播放
     */
    private boolean isAutoPlay = false;

    /**
     * 是否重复播放
     */
    private boolean isRepeatPlay = false;

    /**
     * 是否已经准备好了  能播放了
     */
    private boolean isPrePared = false;

    /**
     * 用户交互的回调事件
     */
    private PlayVideoListener playVideoListener;

    private View view;
    private Surface surface;
    private YXJTextureView textureView;
    private SurfaceTexture mSurfaceTexture;
    private MediaPlayer mMediaPlayer;
    /**
     * 控制view
     */
    private MediaPlayerControlView mMediaPlayerControlView;
    /**
     * 定时器  用于计算播放进度
     */
    private Timer UPDATE_PROGRESS_TIMER;
    private ProgressTimerTask mProgressTimerTask;
    private View layRootVIew;

    /**
     * 是否暂停
     */
    public boolean isPause = false;

    public boolean isPrePared() {
        return isPrePared;
    }

    /**
     * 正在播放
     *
     * @return
     */
    public boolean isPlaying() {
        return state == YXJVideoConstant.STATE_PLAYING;
    }

    public YXJVideoView(Context context) {
        this(context, null);
    }


    public YXJVideoView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public YXJVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        addView(view = LayoutInflater.from(context).inflate(R.layout.video_layout, this, false));
        layRootVIew = view.findViewById(R.id.layRootVIew);
        textureView = view.findViewById(R.id.mYXJTextureView);
        mMediaPlayerControlView = view.findViewById(R.id.mMediaPlayerControlView);
        mMediaPlayerControlView.setControlPlayListener(controlPlayListener);
        initMediaPlayer();
    }


    public <T> YXJVideoView setBackground(T t) {
        if (t != null) {
            if (t instanceof Integer) {
                layRootVIew.setBackgroundResource((Integer) t);
            }

            if (t instanceof Drawable) {
                layRootVIew.setBackground((Drawable) t);
            }
        }
        return this;
    }


    public <T> YXJVideoView setBgColor(int color) {
        layRootVIew.setBackgroundColor(color);
        return this;
    }


    /**
     * @param drawable
     * @param margin
     */
    public YXJVideoView setHeadCancelIcon(Drawable drawable, MarginLayoutParams margin) {
        mMediaPlayerControlView.setHeadCancelIcon(drawable, margin);
        return this;
    }

    /**
     * @param playVideoListener
     * @return
     */
    public YXJVideoView setPlayVideoListener(PlayVideoListener playVideoListener) {
        this.playVideoListener = playVideoListener;
        mMediaPlayerControlView.setPlayVideoListener(playVideoListener);
        return this;
    }


    /**
     * 是否支持点击视频
     *
     * @param b
     */
    public YXJVideoView setSupportOnClick(boolean b) {
        mMediaPlayerControlView.setSupportOnClick(b);
        return this;
    }


    /**
     * 是否支持长按事件
     *
     * @param supportOnLongClick
     */
    public YXJVideoView setSupportOnLongClick(boolean supportOnLongClick) {
        mMediaPlayerControlView.setSupportOnLongClick(supportOnLongClick);
        return this;
    }


    /**
     * 是否支持播放头
     *
     * @param b
     */
    public YXJVideoView setSupportHeadView(boolean b) {
        mMediaPlayerControlView.setSupportHeadView(b);
        return this;
    }


    /**
     * 是否支持沉嵌式状态栏
     *
     * @param supportSubmergedBar
     */
    public YXJVideoView setSupportSubmergedBar(boolean supportSubmergedBar) {
        mMediaPlayerControlView.setSupportSubmergedBar(supportSubmergedBar);
        return this;
    }


    /**
     * 添加扩展view
     */
    public YXJVideoView addHeadView(View view) {
        mMediaPlayerControlView.addHeadView(view);
        return this;
    }


    /**
     * 设置默认加载动画
     *
     * @param mode
     */
    public YXJVideoView setDefaultLoad(VideoLoadView.LoadAnimMode mode) {
        mMediaPlayerControlView.setDefaultLoad(mode);
        return this;
    }


    /**
     * 设置默认加载动画
     *
     * @param drawable
     */
    public YXJVideoView setLoadAnim(Drawable drawable) {
        mMediaPlayerControlView.setLoadAnim(drawable);
        return this;
    }


    /**
     * 自动播放
     *
     * @param autoPlay
     */
    public YXJVideoView setAutoPlay(boolean autoPlay) {
        isAutoPlay = autoPlay;
        return this;
    }

    /**
     * 是否支持控制
     *
     * @param supportControl
     */
    public YXJVideoView setSupportControl(boolean supportControl) {
        mMediaPlayerControlView.setSupportControl(supportControl);
        return this;
    }

    /**
     * 暂停icon资源图片
     */
    public YXJVideoView setPauseIcon(Drawable pauseIcon) {
        mMediaPlayerControlView.setPauseIcon(pauseIcon);
        return this;
    }

    /**
     * 播放icon資源图片
     */
    public YXJVideoView setPlayIcon(Drawable playIcon) {
        mMediaPlayerControlView.setPlayIcon(playIcon);
        return this;
    }

    /**
     * 中心播放按钮icon资源
     */
    public YXJVideoView setCenterPlayIcon(Drawable centerPlayIcon) {
        mMediaPlayerControlView.setCenterPlayIcon(centerPlayIcon);
        return this;
    }

    /**
     * 是否支持重复播放
     *
     * @param repeatPlay
     */
    public YXJVideoView setRepeatPlay(boolean repeatPlay) {
        isRepeatPlay = repeatPlay;
        return this;
    }


    /**
     * 播放器
     */
    private void initMediaPlayer() {
        mMediaPlayer = new MediaPlayer();
    }


    /**
     * @param place
     */
    public YXJVideoView setPlaceHolder(String place) {
        if (mMediaPlayerControlView != null) {
            mMediaPlayerControlView.setPlaceHolder(place);
        }
        return this;
    }


    /**
     * 播放资源视频
     *
     * @param path
     */
    public YXJVideoView setDataSource(String path) throws IOException {
        if (mMediaPlayer == null) {
            initMediaPlayer();
        }
        textureView.setSurfaceTextureListener(this);
        mMediaPlayer.setDataSource(path);
        mMediaPlayer.prepareAsync();
        mMediaPlayer.setOnPreparedListener(onPreparedListener);
        mMediaPlayer.setOnInfoListener(onInfoListener);
        mMediaPlayer.setOnErrorListener(onErrorListener);
        mMediaPlayer.setOnBufferingUpdateListener(onBufferingUpdateListener);
        mMediaPlayer.setOnCompletionListener(completionListener);
        mMediaPlayerControlView.init();
        return this;
    }


    /**
     * 渲染数据
     */
    private void initSurface() {
        if (mSurfaceTexture != null && mMediaPlayer != null) {
            surface = new Surface(mSurfaceTexture);
            mMediaPlayer.setSurface(surface);
        }
    }


    /**
     * 控制界面的功能按钮
     */
    private ControlPlayListener controlPlayListener = new ControlPlayListener() {


        @Override
        public void play() {
            start();
        }

        @Override
        public void pause() {
            pausePlay();
        }

        @Override
        public void onSeekBar(int p) {
            if (state == YXJVideoConstant.STATE_PLAYING
                    ||
                    state == YXJVideoConstant.STATE_PAUSE) {
                seekTo((int) (totalLength * (p * 1.0 / 100)));
                start();
            }
        }

        @Override
        public int playState() {
            return state;
        }


        @Override
        public void playVolume() {
            if (isVolumeClose()) {
                openVolume();
            } else {
                closeVolume();
            }
        }
    };


    MediaPlayer.OnPreparedListener preparedListener;

    public void setPreparedListener(MediaPlayer.OnPreparedListener preparedListener) {
        this.preparedListener = preparedListener;
    }

    /**
     * 視頻准备
     */
    MediaPlayer mp;
    private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {

        @Override
        public void onPrepared(MediaPlayer mp) {
            YXJVideoView.this.mp = mp;
            if (preparedListener != null) {
                preparedListener.onPrepared(mp);
            }
            isPrePared = true;

            state = YXJVideoConstant.STATE_PREPARED;

            mMediaPlayerControlView.onPrepared(mp);

            mMediaPlayerControlView.onProgress(totalLength = mp.getDuration(), mp.getCurrentPosition());

            //显示样式
            showScreenSizeStyle();

            if (isAutoPlay && !isPause) {
                /**
                 *  自动播放功能
                 */
                start();
            }

            Log.v("[YXJVideo]->", "OnPrepared-");
        }
    };


    View container;

    public YXJVideoView setContainerView(View container) {
        this.container = container;
        return this;
    }

    /**
     * 显示大小样式
     */
    public void showScreenSizeStyle() {

        if (mp == null) return;

        if (container == null) {
            textureView.setFixSize(mp.getVideoWidth(), mp.getVideoHeight());
            return;
        }

        //是否开启自动适配视频大小
        checkAutoScreenSizeStyle();

        int mpW = mp.getVideoWidth();
        int mpH = mp.getVideoHeight();
        Log.v("", "[adjustTextureViewSize]->" +
                new StringBuffer()
                        .append("mpW=" + mpW)
                        .append("\n")
                        .append("mpH=" + mpH));

        switch (screenSizeStyle) {
            case none:
                textureView.setFixSize(mpW, mpH);
                mMediaPlayerControlView.setPlaceHolderSize(container.getMeasuredWidth(), container.getMeasuredWidth());
                break;
            case widthFull:
                int w = container.getMeasuredWidth();
                adjustTextureViewSize(w, (int) (mpH * 1.0f / mpW * w));
                break;
            case heightFull:
                int h = container.getMeasuredHeight();
                adjustTextureViewSize((int) (mpW * 1.0f / mpH * h), h);
                break;
        }
    }



    public void setPlaceHolderSize(int w, int h) {
        mMediaPlayerControlView.setPlaceHolderSize(w, h);
    }


    /**
     * @param w
     */
    public void setAdjustTextureViewSize(int w) {
        if (mp == null) return;
        int mpW = mp.getVideoWidth();
        int mpH = mp.getVideoHeight();
        adjustTextureViewSize(w, (int) (mpH * 1.0f / mpW * w));
    }

    /**
     * @param w
     */
    public void setAdjustTextureViewSize(int w, int h) {
        if (mp == null) return;
        int mpW = mp.getVideoWidth();
        int mpH = mp.getVideoHeight();
        float rw = w * 1f / mp.getVideoWidth();
        float rh = h * 1f / mp.getVideoHeight();
        if (rw > rh) {
            adjustTextureViewSize((int) (mpW * 1.0f / mpH * h), h);
        } else {
            adjustTextureViewSize(w, (int) (mpH * 1.0f / mpW * w));
        }
    }

    /**
     * 检测是否自动开启适配适配大小
     */
    private void checkAutoScreenSizeStyle() {
        if (autoScreenSizeStyle) {
            float rw = container.getMeasuredWidth() * 1f / mp.getVideoWidth();
            float rh = container.getMeasuredHeight() * 1f / mp.getVideoHeight();
            if (rh > rw) {
                screenSizeStyle = ScreenSizeStyle.heightFull;
            } else if (rh < rw) {
                screenSizeStyle = ScreenSizeStyle.widthFull;
            } else {
                screenSizeStyle = ScreenSizeStyle.none;
            }
        }
        if (autoScreenSizeStyle1) {
            float rw = container.getMeasuredWidth() * 1f / mp.getVideoWidth();
            float rh = container.getMeasuredHeight() * 1f / mp.getVideoHeight();
            if (rh > rw) {
                screenSizeStyle = ScreenSizeStyle.widthFull;
            } else if (rh < rw) {
                screenSizeStyle = ScreenSizeStyle.heightFull;
            } else {
                screenSizeStyle = ScreenSizeStyle.none;
            }
        }
    }

    public boolean isRectVideo() {
        return mp != null && mp.getVideoHeight() == mp.getVideoWidth();
    }

    //铺满 被裁减
    private boolean autoScreenSizeStyle = false;

    public YXJVideoView setAutoScreenSizeStyle(boolean autoScreenSizeStyle) {
        this.autoScreenSizeStyle = autoScreenSizeStyle;
        return this;
    }


    //按照视频原始显示 不会被裁减
    private boolean autoScreenSizeStyle1 = false;

    public YXJVideoView setAutoScreenSizeStyle1(boolean autoScreenSizeStyle1) {
        this.autoScreenSizeStyle1 = autoScreenSizeStyle1;
        return this;
    }

    private ScreenSizeStyle screenSizeStyle = ScreenSizeStyle.none;

    public YXJVideoView setScreenSizeStyle(ScreenSizeStyle screenSizeStyle) {
        this.screenSizeStyle = screenSizeStyle;
        return this;
    }

    public enum ScreenSizeStyle {
        none, widthFull, heightFull
    }


    /**
     * 宽度铺满
     */
    private void adjustTextureViewSize(int w, int h) {
        ViewGroup.LayoutParams layoutParams = textureView.getLayoutParams();
        layoutParams.width = w;
        layoutParams.height = h;
        textureView.setLayoutParams(layoutParams);
        Log.v("", "[adjustTextureViewSize]->" + new StringBuffer().append("w=" + w).append("\n").append("h=" + h).toString());
        mMediaPlayerControlView.setPlaceHolderSize(w, h);
    }


    /**
     * 播放完成
     */
    private MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            mMediaPlayerControlView.onComplete();
            mMediaPlayerControlView.onProgress(totalLength, totalLength);
            cancelProgressTimer();
            state = YXJVideoConstant.STATE_COMPLETE;
            Log.v("[YXJVideo]->", "OnCompletion-");

            if (isRepeatPlay) {
                resetPlay();
            }
        }
    };


    /**
     * 视频信息
     */
    private MediaPlayer.OnInfoListener onInfoListener = new MediaPlayer.OnInfoListener() {

        @Override
        public boolean onInfo(MediaPlayer mp, int what, int extra) {
            Log.v("[YXJVideo]->", "OnInfoList-》what=" + what + ",extra=" + extra);
            return false;
        }
    };


    /**
     * 错误
     * <p>
     * 可以通过what和extra知道发生了什么错误，
     * <p>
     * 常见的what错误：
     * MEDIA_ERROR_UNKNOWN（1），未指定的错误
     * MEDIA_ERROR_SERVER_DIED（100），media server died，需要释放当前media player，创建一个新的mediaplayer
     * <p>
     * 常见的extra错误：
     * MEDIA_ERROR_IO（-1004），io错误，文件或者网络相关错误
     * MEDIA_ERROR_MALFORMED（-1007），音视频格式错误，demux或解码错误
     * MEDIA_ERROR_UNSUPPORTED（-1010），不支持的音视频格式
     * MEDIA_ERROR_TIMED_OUT（-110），操作超时，通常是超过了3—5秒
     * MEDIA_ERROR_SYSTEM（ -2147483648），系统底层错误
     */
    private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            Log.v("[YXJVideo]->", "OnErrorList-》what=" + what + ",extra=" + extra);
            state = YXJVideoConstant.STATE_ERROR;
            mMediaPlayerControlView.onError(mp, what, extra);
            return true;
        }
    };


    /**
     * 緩冲更新
     */
    private MediaPlayer.OnBufferingUpdateListener onBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {

        @Override
        public void onBufferingUpdate(MediaPlayer mp, int percent) {
            Log.v("[YXJVideo]->", "onBufferingUpdate-》percent=" + percent);
            mMediaPlayerControlView.onBufferingUpdate(percent);
        }
    };


    /**
     * 播放进度
     */
    public class ProgressTimerTask extends TimerTask {
        @Override
        public void run() {
            try {
                if (mMediaPlayer != null && mMediaPlayerControlView != null) {
                    if (state == YXJVideoConstant.STATE_PLAYING
                            || state == YXJVideoConstant.STATE_PAUSE) {
                        post(new Runnable() {
                            @Override
                            public void run() {
                                mMediaPlayerControlView.onProgress(
                                        mMediaPlayer.getDuration(),
                                        mMediaPlayer.getCurrentPosition());
                                showBuffering();
                            }
                        });
                    }
                }
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 是否加载中
     * <p>
     * 加载动画转圈
     */
    private void showBuffering() {
        currentProgress = mMediaPlayer.getCurrentPosition();
        Log.v("[YXJVideo]->", "onBuffering-》currentProgress=" + currentProgress + ",oldProgress=" + oldProgress);
        if (state == YXJVideoConstant.STATE_PLAYING) {
            mMediaPlayerControlView.onBuffering(currentProgress == oldProgress);
        } else {
            mMediaPlayerControlView.onBuffering(false);
        }
        oldProgress = currentProgress;
    }


    /**
     * 开始计时
     */
    private void startProgressTimer() {
        cancelProgressTimer();
        UPDATE_PROGRESS_TIMER = new Timer();
        mProgressTimerTask = new ProgressTimerTask();
        UPDATE_PROGRESS_TIMER.schedule(mProgressTimerTask, 0, 300);
    }


    /**
     * 取消进度
     */
    private void cancelProgressTimer() {
        if (UPDATE_PROGRESS_TIMER != null) {
            UPDATE_PROGRESS_TIMER.cancel();
        }
        if (mProgressTimerTask != null) {
            mProgressTimerTask.cancel();
        }
    }


    /**
     * 开始播放
     */
    public void start() {
        if (mMediaPlayer != null) {
            isPause = false;
            mMediaPlayer.start();
            mMediaPlayerControlView.onStart();
            startProgressTimer();
            state = YXJVideoConstant.STATE_PLAYING;
        }
    }


    /**
     * 暂停播放
     */
    public void pausePlay() {
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            isPause = true;
            mMediaPlayer.pause();
            mMediaPlayerControlView.onPause();
            cancelProgressTimer();
            state = YXJVideoConstant.STATE_PAUSE;
        }
    }


    /**
     * 停止  销毁
     * <p>
     * 销毁播放器
     */
    public void stop() {
        isPause = false;
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }

        if (mSurfaceTexture != null) {
            mSurfaceTexture.release();
            mSurfaceTexture = null;
        }

        cancelProgressTimer();
        mMediaPlayerControlView.onStop();

        state = YXJVideoConstant.STATE_NONE;
    }


    /**
     * 指定位置播放
     *
     * @param p
     */
    public void seekTo(int p) {
        mMediaPlayer.seekTo(p);
    }


    /**
     * 重播
     */
    public void resetPlay() {
        mMediaPlayer.seekTo(0);
        start();
        mMediaPlayerControlView.onResetPlay();
    }


    /**
     * 静音
     */
    public void closeVolume() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setVolume(0, 0);
            isVolumeClose = true;
            mMediaPlayerControlView.setVolumeClose(true);
        }
    }


    /**
     * 音量是否开启
     */
    boolean isVolumeClose = true;

    public boolean isVolumeClose() {
        return isVolumeClose;
    }


    /**
     * 静音
     */
    public void openVolume() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setVolume(1, 1);
            isVolumeClose = false;
            mMediaPlayerControlView.setVolumeClose(false);
//            AudioManager audioManager=(AudioManager)getContext().getSystemService(Service.AUDIO_SERVICE);
//            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM);
//            mMediaPlayer.setVolume(audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM), audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
        }
    }


    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Log.v("[surfaceTexture]->", "onSurfaceTextureAvailable");
        if (mSurfaceTexture == null) {
            mSurfaceTexture = surface;
            initSurface();
        } else {
            textureView.setSurfaceTexture(mSurfaceTexture);
        }
        mMediaPlayerControlView.isSurfaceTextureAvailable(true);
    }


    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }
}
